#pragma once

#include<iostream>
#include<string>
#include<cstring>
#include<cerrno>
#include<cstdlib>
#include<strings.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>

#include"err.hpp"

namespace nt_client
{
    class Udpclient
    {
    public:
        Udpclient(std::string ip,uint16_t port)
        :_Serverip(ip),_Serverport(port)
        {

        }

        ~Udpclient()
        {

        }

        void InitClient()
        {
            //1.创建套接字
            _sock=socket(AF_INET,SOCK_DGRAM,0);

            if(_sock==-1)
            {
                std::cout<<"Create socket fail:"<<strerror(errno)<<std::endl;
                exit(SOCKET_ERR);
            }

            std::cout<<"Create socket success"<<_sock<<std::endl;

            //2.构建服务器端的sockaddr_in结构体信息
            bzero(&_serve,sizeof(_serve));
            _serve.sin_family=AF_INET;
            _serve.sin_addr.s_addr=inet_addr(_Serverip.c_str());
            _serve.sin_port=htons(_Serverport);



        }

        void StartClient()
        {
            char buff[1024];

            while(true)
            {
                //1.发送消息
                std::string msg;
                std::cout<<"Input Message# ";
                std::getline(std::cin,msg);

                ssize_t n=sendto(_sock,msg.c_str(),msg.size(),0,(const struct sockaddr*)&_serve,sizeof(_serve));
            
                if(n==-1)
                {
                    std::cout<<"Sent Message Fail:"<<strerror(errno)<<std::endl;
                    continue;
                }

                //2.接受消息
                socklen_t len=sizeof(_serve);
                n=recvfrom(_sock,buff,sizeof(buff)-1,0,(struct sockaddr*)&_serve,&len);

                if(n>0)
                    buff[n]='\0';
                elseg
                    continue;

                std::string ip=inet_ntoa(_serve.sin_addr);
                uint16_t port=ntohs(_serve.sin_port);

                printf("Client get message form [%s:%d]# %s\n",ip.c_str(),port,buff);

            }
        }

    private:
        std::string _Serverip;
        uint16_t _Serverport;
        int _sock;
        struct sockaddr_in _serve;
    };
}